/*
 *  $Id: ElementValues.cs 1200 2010-11-22 12:19:43Z thenn.erannor $
 *	This file is a part of Ragima CCG.
 *	(C) 2008-2009 Ragima development group.
 *
 *	Licensed under the terms of the GNU GPL License version 2.
 *
 */

using Nereal.Serialization;

namespace Ragima {
    [ConstructorParameters("DefaultValue")]
    public sealed class ElementValues {
        private int _defValue;
        private int[] _values;

        public ElementValues(): this(0) {}
        public ElementValues(int defValue) {
            _defValue = defValue;
            _values = new int[ElementType.Count];
            Clear();
        }

        [XmlName("default"), DefaultValue(0)]
        public int DefaultValue {
            get { return _defValue; }
        }

        [XmlName(ElementType.NeutralId)]
        public int NeutralValue {
            get { return this[ElementType.Neutral]; }
            set { this[ElementType.Neutral] = value; }
        }

        [XmlName(ElementType.LightId)]
        public int LightValue {
            get { return this[ElementType.Light]; }
            set { this[ElementType.Light] = value; }
        }

        [XmlName(ElementType.DarknessId)]
        public int DarknessValue {
            get { return this[ElementType.Darkness]; }
            set { this[ElementType.Darkness] = value; }
        }

        [XmlName(ElementType.FireId)]
        public int FireValue {
            get { return this[ElementType.Fire]; }
            set { this[ElementType.Fire] = value; }
        }

        [XmlName(ElementType.WaterId)]
        public int WaterValue {
            get { return this[ElementType.Water]; }
            set { this[ElementType.Water] = value; }
        }

        [XmlName(ElementType.EarthId)]
        public int EarthValue {
            get { return this[ElementType.Earth]; }
            set { this[ElementType.Earth] = value; }
        }

        [XmlName(ElementType.AirId)]
        public int AirValue {
            get { return this[ElementType.Air]; }
            set { this[ElementType.Air] = value; }
        }

        public int this[ElementType element] {
            get { return _values[element.Number]; }
            set { _values[element.Number] = value; }
        }

        public bool Empty {
            get {
                for (int i = 0; i < _values.Length; i++)
                    if (_values[i] != _defValue)
                        return false;
                return true;
            }
        }

        public int Sum {
            get {
                int sum = 0;
                for (int i = 0; i < _values.Length; i++)
                    sum += _values[i];
                return sum;
            }
        }

        public void Clear() {
            for (int i = 0; i < _values.Length; i++)
                _values[i] = _defValue;
        }

        public ElementValues Clone() {
            var values = new ElementValues(_defValue);
            for (int i = 0; i < _values.Length; i++)
                values._values[i] = _values[i];
            return values;
        }

        public void Increment(ElementType element) {
            _values[element.Number]++;
        }
        public void Increment(ElementType element, int value) {
            _values[element.Number] += value;
        }
        public void Increment(ElementValues values) {
            foreach (var element in ElementType.AllElements)
                _values[element.Number] += values[element];
        }
        public void Decrement(ElementType element) {
            _values[element.Number]--;
        }
        public void Decrement(ElementType element, int value) {
            _values[element.Number] -= value;
        }
        public void Decrement(ElementValues values) {
            foreach (var element in ElementType.AllElements)
                _values[element.Number] -= values[element];
        }
    }
}
